package cn.yitun.chat.yitunservermanagecore.general.manage.core.manager;

import cn.yitun.chat.yituncommonmessage.ExceptionEnum;
import cn.yitun.chat.yituncommonmessage.Info;
import cn.yitun.chat.yituncommonutil.YitunMD5Util;
import cn.yitun.chat.yituncommonutil.YitunRegexUtil;
import cn.yitun.chat.yituncommonutil.YitunStringUtil;
import cn.yitun.chat.yituncommonutil.YitunTimeStampUtil;
import cn.yitun.chat.yitunservercommonlib.basebean.web.JwtUserDto;
import cn.yitun.chat.yitunservercommonlib.constant.RedisConstant;
import cn.yitun.chat.yitunservercommonlib.dataentity.dto.system.user.UserDto;
import cn.yitun.chat.yitunservercommonlib.dataentity.dto.userchat.UserNumberDto;
import cn.yitun.chat.yitunservercommonlib.dataentity.po.system.user.UserInfo;
import cn.yitun.chat.yitunservercommonlib.dataentity.vo.system.user.UserVo;
import cn.yitun.chat.yitunservercommonlib.event.DataEvent;
import cn.yitun.chat.yitunservercommonlib.event.UpdateEvent;
import cn.yitun.chat.yitunservercommonlib.util.JwtUtil;
import cn.yitun.chat.yitunservercommonlib.util.codec.IdGen;
import cn.yitun.chat.yitunserverimbase.dao.system.UserDao;
import cn.yitun.chat.yitunserverimbase.dao.userchat.UserHeadDao;
import cn.yitun.chat.yitunserverimbase.dao.userchat.UserNumberDao;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * Date 2019-01-20 10:21:23<br>
 * Description
 * 
 * @author yitun<br>
 * @version 1.1
 */
@Service
public class UserManager {

	@Resource
	private UserDao userDAO;
	@Resource
	private UserHeadDao userHeadDAO;
	@Resource
	private UserNumberDao numberDAO;

	private static final Gson gson = new GsonBuilder().create();
//	@Resource
//	private UserCache userCache;
	/**
	 * 这是用户新建后需要初始化的一些事件，这样是为了方便解耦和再不修改代码的情况下添加代码
	 */
	private List<DataEvent<Long>> userInitializeDataEventList = new ArrayList<>();

	private List<DataEvent<Long>> userUpdateDataEventList = new ArrayList<>();
	private List<DataEvent<Long>> userUpdateHeadEventList = new ArrayList<>();
//	private List<UpdateEvent<Long, String>> userUpdateStatusEventList = new ArrayList<>();
	private List<UpdateEvent<Long, String>> userUpdateChatOnlineEventList = new ArrayList<>();
	private List<UpdateEvent<Long, String>> userUpdateSignatureEventList = new ArrayList<>();

	public void addInitializeDataEvent(DataEvent<Long> de) {
		userInitializeDataEventList.add(de);
	}

	public void addUpdateDataEvent(DataEvent<Long> de) {
		userUpdateDataEventList.add(de);
	}

	public void addUpdateHeadEvent(DataEvent<Long> de) {
		userUpdateHeadEventList.add(de);
	}

//	public void addUpdateStatusEvent(UpdateEvent<Long, String> de) {
//		userUpdateStatusEventList.add(de);
//	}

	public void addUpdateChatOnlineEvent(UpdateEvent<Long, String> de) {
		userUpdateChatOnlineEventList.add(de);
	}

	public void addUpdateSignatureEvent(UpdateEvent<Long, String> de) {
		userUpdateSignatureEventList.add(de);
	}

	private void initialize(Long userId) {
		for (DataEvent<Long> de : userInitializeDataEventList) {
			de.event(userId);
		}
	}

	public void updateData(Long userId) {
		for (DataEvent<Long> de : userUpdateDataEventList) {
			de.event(userId);
		}
	}

	public void updateHead(Long userId) {
		for (DataEvent<Long> de : userUpdateHeadEventList) {
			de.event(userId);
		}
	}

//	public void updateStatus(Long userId, String status) {
//		for (UpdateEvent<Long, String> de : userUpdateStatusEventList) {
//			de.event(userId, status);
//		}
//	}

	public void updateChatOnlineStatus(Long userId, String chatOnline) {
		for (UpdateEvent<Long, String> de : userUpdateChatOnlineEventList) {
			de.event(userId, chatOnline);
		}
	}

	public void updateSignature(Long userId, String signature) {
		for (UpdateEvent<Long, String> de : userUpdateSignatureEventList) {
			de.event(userId, signature);
		}
	}

	/**
	 * 
	 * Description 新增用户 <br>
	 * Date 2019-04-27 15:46:11<br>
	 * 
	 * @param user
	 * @return Info
	 * @version 1.1
	 */
	public Info add(UserDto user) {
		Info info = check(user);
		if (info.isSuccess()) {
			long i = new Random().nextLong();
			i = i + 1;
			UserNumberDto userNumber = new UserNumberDto();// 生成数子账号
			userNumber.setCode(IdGen.uuid());
			numberDAO.save(userNumber);

			// user.setAccount(userNumber.getId() + "");
			user.setCreateBy(0l);
			user.setUpdateBy(0l);
			user.setPrivateKey(IdGen.uuid());
			user.setPassword(YitunMD5Util.md5L32(user.getPassword()));
			user.setCode(userNumber.getCode());
			user.setHead(i);
			userDAO.save(user);
			initialize(user.getId());
		}
		return info;
	}

	public Info update(UserDto user) {
		Info info = check(user);
		if (info.isSuccess()) {
			int mark = userDAO.update(user);
			if (mark <= 0) {
				info.addWarning(ExceptionEnum.DO_FAIL);
			} else {
				updateData(user.getId());
			}
		}
		return info;
	}

	private Info check(UserDto user) {
		Info info = new Info();
		String account = user.getAccount();
		String email = user.getEmail();
		String mobile = user.getMobile();
		Long userId = user.getId() == null ? null : user.getId();

		if (!YitunRegexUtil.isAccount(account)) {
			info.addWarning(ExceptionEnum.ACCOUNT_PATTERN_ERROR);
		}

		if (YitunStringUtil.isNotEmpty(email)) {
			if (!YitunRegexUtil.isEmail(email)) {
				info.addWarning(ExceptionEnum.USER_EMAIL_PATTERN_ERROR);
			} else {
				if (this.isExistEmail(userId, email)) {
					info.addWarning(ExceptionEnum.USER_EMAIL_EXISTS);
				}
			}
		}

		if (YitunStringUtil.isNotEmpty(mobile)) {
			if (!YitunRegexUtil.isMobile(mobile)) {
				info.addWarning(ExceptionEnum.USER_PHONE_PATTERN_ERROR);
			} else {
				if (this.isExistMobile(userId, mobile)) {
					info.addWarning(ExceptionEnum.USER_PHONE_EXISTS);
				}
			}
		}

		if (info.isSuccess()) {
			if (isExistAccount(userId, account)) {
				info.addWarning(ExceptionEnum.ACCOUNT_EXISTS);
			}
		}
		return info;
	}

	/**
	 * 
	 * Date 2019-01-20 13:07:08<br>
	 * Description 获取用户信息
	 * 
	 * @author yitun<br>
	 * @param id
	 * @return
	 * @version 1.1
	 */
	public UserVo getUserDataById(Long id) {
		return userDAO.getVO(id);
	}

	/**
	 * 当前用户账号是否存在
	 * @param userId
	 * @param account
	 * @return
	 */
	public boolean isExistAccount(Long userId, String account) {
		UserInfo u = userDAO.getUserByAccount(account);
		return null != u && u.getId().equals(userId);
	}

	/**
	 * 当前用户邮箱是否存在
	 * @param userId
	 * @param email
	 * @return
	 */
	public boolean isExistEmail(Long userId, String email) {
		UserInfo u = userDAO.getUserByEmail(email);
		return null != u && u.getId().equals(userId);
	}

	/**
	 * 当前用户手机号是否存在
	 * @param userId
	 * @param mobile
	 * @return
	 */
	public boolean isExistMobile(Long userId, String mobile) {
		UserVo u = userDAO.getUserVOByMobile(mobile);
		return null != u && u.getId().equals(userId);
	}


	public void sendChatOnlineStatus(Long userId, String status) {
		this.updateChatOnlineStatus(userId, status);
	}

}
